﻿<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="AAuto" /> 
<title>JS与AAuto语法比较(面向对象部份)</title>
<link href="../style.css" rel="stylesheet" type="text/css" />
</head>

<body>
<div id="maincontent">
<h1>JS与AAuto语法比较(面向对象部份)</h1>
 <div class="desc">参考:<a href="../libraries/std/web/html.html"></a><a href="external.html">在网页脚本中调用AAuto函数</a><a href="doScript.html"></a> <a href="doScript.html">在AAuto中执行网页脚本</a></div>
 <div>
    <h2>概述</h2>
  <p>Javascript在web编程、网页编程中是最重要的一种客户端脚本语言，而在AAuto程序设计中，他又具有了一些新的应用，例如Web UI界面设计，通过AAuto也扩展了Javascript的本地化编程应用，而Javascript也很好的扩展了AAuto的功能。  </p>
  <p>Javascript、AAuto的语法都是基于C系语法，而且同是动态语言，语法特性非常接近。而在AAuto的Web编程中，Javascript可能是大家接触最多的语言。了解两种语法的异同有助于同时加深对Javascript,AAuto两种语言的理解。<br />
  </p>
  <p>本文适合至少熟练掌握这两种语言中其中一种的用户，如果你熟悉Javascript或AAuto,本文将有助于你快速的掌握另外一种语言.</p>
  <p>AAuto与Javascript的语法差异主要表现在面向对象有关的一些语法上。<br />
  下面我们以此为重点介绍两种语言在实现面向对象特性时的一些语法区别.</p>
  参考资料: 
 <a href="../the language/class/class.html">AAuto中的类</a></div><div>
  <h2>数据集合<br />
  </h2>
  <p>在AAuto中表示数据集合只有一种对象，即<a href="../the language/datatype/datatype.html#vartable">table对象</a>，table对象不但可以包含键值对，而且可以包含数组，<a href="../the language/datatype/datatype.html#vartable">table对象</a>所有成员放在大括号中，并用分号分隔。</p>
  <div class="quote">AAuto用大括号表示集合，无论是指令集合(语句块)，还是数据集合(table)<br />
    并且使用分号分隔元素，无论是指令元素(语句)，还是数据成员(table成员)<br />
    保持语法的简洁，和概念一致性。  </div>
  <p><strong>例如：</strong></p>
  <pre><span class="imp">//AAuto代码:</span>

var tab = {

    123;456;789;
    name = "张三";
    gohome = function(){
        io.print(&quot;I'm back&quot;)
    }

}

io.print( tab.name ) //显示 张三
io.print( tab[1] ) //显示123</pre> 
  <p>&nbsp;</p>
  <p>而在Javascript，分为对象字面量,以及数组。</p>
  <div class="tip">字面量(Literals)：有时候叫直接量,对象直接量指的是定义对象的代码构造的匿名对象,因为对象在创建时还没有名字,表示的就是代码描述的值,即字面值或字面量.</div>
  <p>对象字面量,用冒号分隔键值对，而使用逗号分隔成员，例如:</p>
  <pre><span class="imp">//Javascript代码</span>

var tab = {
    name:"张三",
    gohome:function(){
        document.write(&quot;I'm back&quot;)
    }

}

document.write(tab.name); //显示 张三 </pre>
  <p>上面的冒号用的有些怪异,在AAuto中取而代之的是等号.</p>
  <p>数组则放在中括号中，并使用逗号来分隔。</p>
 
  <pre><span class="imp">//Javascript代码</span>

var tab = [123,456,789] 
document.write(tab[1]); //显示 123</pre>
 
  <br />
  AAuto在创建数组时仍然使用大括号，并且分号分隔元素。
 </div> <div>
   <h2>类</h2>
   <p>Javascript中没有明确类的概念，也没有相关的语法关键字，而普通的对象，函数可都以模拟类的作部份功能.<br />
    用new关键词创建对象的副本，实际上这种过于的自由,一定程度上增加了学习理解、记忆的难度，新手要完全理解JS的面象对象机制有一定的难度.</p>
   <p>用普通数据对象模拟类的实现<br />
   <pre><span class="imp">//Javascript代码</span>

var test = {}
test2 = new test; <span class="comment">//当你使用new关键字,对象就模拟类的功能创建新的实例.</span></pre>
     <p>AAuto中并不认为table对象是类,仅仅是提供了简单的深拷贝函数复制table对象,如下:<br />
     <pre><span class="imp">//AAuto代码:</span>

var test ={}
var test_new = table.clone(test)</pre>
       <br />
       <br />
    Javascript也可以用函数来模拟实现类，你如果习惯使用传统语言,可能有些难以理解,实际上你可以当他是一个类的构造函数.这种隐晦传递的语义使JS构建类的代码不太好理解.
     <pre><span class="imp">//Javascript代码</span>

function myclass(){
    this.name = "张三";
    this.getName = function(){
        return this.name;
    }
    this.setName = function(name){
        this.name = name;
    }
}
   </pre>
   <p>在构造函数中,使用this表示创建的对象实例(每次运行构造函数会创建不同的对象实例)<br />
    这一点与AAuto非常相似,在AAuto的构造函数中,同样可以使用this访问对象实例.</p>
   <pre><span class="imp">//AAuto代码:</span>

<span class="kw">class</span> myclass{

    <span class="kw">ctor</span>(  ){ <span class="comment">//ctor定义类的构造函数</span>
        <span class="kw">this</span>.name = "张三";
        <span class="kw">this</span>.getName = <span class="kw">function</span>(){
            <span class="kw">return</span> this.name;
        }
        <span class="kw">this</span>.setName = <span class="kw">function</span>(name){
            this.name = name;
        }
    };
	
    <span class="comment">//下面的这样增加类实例成员的方法,javascript是不支持的</span>
    age = 23;
    gohome = <span class="kw">function</span>(){
        io.print("I'm back")
    }
 
}
   </pre>
   <p>除了使用this关键字表示实例对象与javascript一致以外.<br />
     AAuto显示的定义一个类,并可以显式的定义类的实例成员,语法更为接近传统编程语言.
   </p>
   <p>而实际上JS用函数构建类,等于仅仅提供了AAuto中<span class="kw">ctor</span>构造函数的功能,这时候函数同时具有多个责任,即表示一个类,又表示一个构造函数,这种设计实际上违背了一个函数一个职责的基本原则。<br />
     <br />
    </div> <div>
    <h2>创建对象实例</h2>
<p>JS用new关键字来创建对象实例 </p>
    <pre>obj = new 函数名或对象名
obj = new 函数名(构造参数)
</pre> 
     <br />
    ,而AAuto不需要使用new关键字,但是必须在后面加上表示调用构造函数的括号,如下：
    <pre>obj = 类名(构造参数)</pre> 
<br />
 </div>
 <div>
    <h2>this的区别</h2>
<p>在Javascript中,使用new关键字创建对象时,函数类似AAuto中的类.</p>
    <pre>obj = new 函数名或对象名
obj = new 函数名(构造参数)
</pre> 
     <br />
    这时候,函数中的this与AAuto中的this一样,都是表示当前创建的对象实例.<br />
    <br />
    <br />
    但是,如果没有使用new关键字,直接调用函数,在Javascript函数中也可以使用this关键字,<br />
    但是这时候表示的只是函数的所有者,也就是AAuto中的owner对象.onwer指的是函数的当前名字空间前缀.<br />
    <br />
    如下JS代码:<br />
<pre>返回值 = 所有者.函数名(参数)</pre>
<br />
上面的所有者就是此函数调用时的owner对象.<br />
当没有名字空间前缀时,AAuto的owner为null空值,而这时候Javascript的this则等价于global全局对象.<br />
<br />
在Javascript中,有较多契约式的设计,例如函数在在一些前提下表示类,一些前提下又表示函数,this在一些前提下表示this,而在一些前提下又表示owner,这种设计风格不但表现在语言层面,也影响到使用Js的程序员,以及一些框架,例如jQuery的参数各种不同的变化可以写出一本厚厚的书. 这也是造成Javascript易学难精的一个主要原因.<br />
 </div>
 <div>
   <h2>原型表</h2>
   <p>javascript可以使用prototype指定对象的原型表 </p>
   <p>例如：</p>
   <pre><span class="imp">//Javascript代码</span>

function myclass(){
    this.name = "张三";
}

myclass.prototype.sex = "男" ;//成员变量
myclass.prototype.getName = function(){    //成员方法
    return this.name;
}

</pre>
   <p>prototype就是一个表,下面的代码也可以写成下面这样:</p>
   <pre><span class="imp">//Javascript代码</span>

function myclass(){}
myclass.prototype = {    
    name:"张三", 
    sex:"男",
    getName:function(){
        return this.name;
    }
};
   </pre>
   <p><br />
     区别是放到了一个表里,并且把等号变成了冒号.</p>
   <p>而在AAuto中可以为一个对象指定元表，元表中的_get元方法则可指定一个原型表.<br />
     AAuto中的元表比JS中的原型表功能更多一些,不但包含可以指定原型表的_get元方法,还可以使用其他的元方法自定义一些对象的行为,重载操作符等等.请参考:<a href="../libraries/kernel/table/meta.html">元表</a> <a href="../the language/operator/overloading.html">重载操作符</a><br />
     <br />
     在AAuto中使用@表示对象的元表,通常在对象后面附加@后缀表示该对象的元表,<br />
     而在表构造器中用@前缀指定的一个元表.<br />
   </p>
   <p>我们可以使用元表实现类似JS中的prototype功能.如下:</p>
   <pre><span class="imp">//AAuto代码:</span>

class myclass{

	ctor( ){
	
	};
	
    @prototype;
}

myclass.prototype._get = {
    name="张三";
    sex="男";
    getName=function(){
        return this.name;
    }; 
        
}</pre>
   <p>AAuto中的元表还可以实现一些更强大的功能,例如属性表:</p>
   <pre><span class="imp">//AAuto代码:</span>

import util.metaProperty

class myclass{
	ctor( /*输入构造函数所需要的参数*/ ){
	
	};
    @metaProperty;
}
 
myclass.metaProperty = util.metaProperty(

	属性 = {
		_get = function(){ 
			/*读取属性代码写在这里*/
			return null;
		}
		_set = function( value ){
			/*写入属性代码写在这里*/
			..io.print( owner,value)
		} 	
	};
	@{ _get = ..父属性表 } /*属性表可继承*/ 
)
</pre>
   <p>属性表可以更好的支持面向对象技术,在AAuto标准库中的应用非常多,例如win.ui.ctrl库.</p>
 </div>
 <div>
   <h2>静态方法</h2>
   <p>一个类创建的所有对象都可以访问的方法称为静态方法.对于一个类,静态方法只有一个实例.不会因为创建新对象而创新建新的静态方法.</p>
   <p>AAuto与JS使用静态方法的语法是一样的,都是在类名后直接跟上静态成员的名字,例如:
   <pre>类名.静态成员名字</pre>
     <br />
     而在C++语言里,也有类似的语法,用::代替.表示静态成员,例如:<br />
   </p>
   <pre>类名::静态成员名字</pre>
   <p>总之跟在类名后面的成员是静态成员,跟在对象名字后面的是实例成员,这在大多数语言中都一致.</p>
 </div> 
 <div>
   <h2>私有成员
</h2>
   <p>在JS以及AAuto中都可以在类的构造函数中用var语句声明私有的局部变量.<br />
   AAuto的构造函数作用域为整个类(与普通函数不同),因此构造函数中定议的局部变量在类定义范围有效，而在类外部无法直接访问。</p>
 </div>
 <div>
   <h2>只读成员</h2>
   <p>在AAuto可以为成员常量添加下划线作为前缀表示只读成员,只读成员一旦初始化以后就不能再修改其值.<br />
   而Javascript中不能定义类的只读成员.</p>
 </div>
 <div>
   <h2>继承 </h2>
   <p>javascript通过prototype实现继承</p>
   <pre><span class="imp">//Javascript代码</span>

function parent(){
    this.familyname = "张"
    this.name = "张三他爸"
    this.getFamilyName  = function(){
        return this.familyname;
    }
}

function child(){
    this.name = "张三";
}
child.prototype = new parent();//注意要用new</pre>
   <p>而在AAuto里继承的方法比较多,一种是类似上面的将原型表指定为父类构建的实例,称为间接继承.<br />
     <br />
   也可以使用更简单的直接继承,如下:<br />
   <pre>
<span class="imp">//AAuto代码:</span>

class parent{
    familyname = "张";
    name = "张三他爸";
    getFamilyName  = function(){
        return this.familyname;
    }
}

class child(){
	ctor(){
		this = ..parent()
	}
    name = "张三";
}
child.prototype = parent();
</pre>
   <br />
   </p>
 </div>
  <div>
    <h2>名字空间</h2>
    <p>在Javascript里对名字空间的支持非常有限,<br />
      而AAuto有非常完整的模块化、名字空间机制，在AAuto中每个类有自已的名字空间,类的名字空间里的成员也是类的静态成员.请注意这方面的差异，具体请查看： <a href="../the language/namespace.html">AAuto的名字空间</a></p>
  </div>
</div>
</body>
</html>